<?php

namespace app\controller;

use AlibabaCloud\Dara\Util\Console;
use app\BaseController;
use AppStoreServerLibrary\AppStoreServerAPIClient;
use AppStoreServerLibrary\AppStoreServerAPIClient\APIException;
use AppStoreServerLibrary\Models\Environment;
use AppStoreServerLibrary\Models\Type;
use AppStoreServerLibrary\SignedDataVerifier;
use AppStoreServerLibrary\Models\NotificationTypeV2;
use AppStoreServerLibrary\Models\Subtype;
use think\facade\Db;
//登录注册控制器
class Appstore extends BaseController
{
    private function load_root_certificates(): array
    {
        $certsPath = app()->getRootPath() . 'app/certs/';
        $certificates = [];
        
        // 加载 0.cer, 1.cer, 2.cer 文件
        for ($i = 0; $i <= 2; $i++) {
            $certPath = $certsPath . $i . '.cer';
            if (file_exists($certPath)) {
                $certContent = file_get_contents($certPath);
                if ($certContent !== false) {
                    $certificates[] = $certContent;
                }
            }
        }
        
        return $certificates;
    }
    
    public function index() {
        $bundleId = env('BUNDLE_ID');
        $environment = env('APPLE_DEBUG') == 1 ? Environment::SANDBOX : Environment::PRODUCTION;
        if (!$this->request->isPost()) {
            return json(['code' => 400, 'msg' => '请求方式错误']);
        }
        // 获取 signedPayload 参数
        $signedPayload = $this->request->post('signedPayload');
        if (empty($signedPayload)) {
            return json(['code' => 400, 'msg' => 'signedPayload 不能为空']);
        }
        try {
            $rootCertificates = $this->load_root_certificates();
            $appAppleId = env('APP_APPLE_ID');
            $enableOnlineChecks = true;
            $signedDataVerifier = new SignedDataVerifier(
                rootCertificates: $rootCertificates,
                enableOnlineChecks: $enableOnlineChecks,
                environment: $environment,
                bundleId: $bundleId,
                appAppleId: $appAppleId
            );
            $result = $signedDataVerifier->verifyAndDecodeNotification($signedPayload);
            $orderInfo = $result->getData()->getSignedTransactionInfo();
            $detail = $signedDataVerifier->verifyAndDecodeSignedTransaction($orderInfo);
            $uuid = $detail->getAppAccountToken();
            $user = Db::name("think_users")->where("uuid",$uuid)->find();
            $notificationType = $result->getNotificationType();
            $subtype = $result->getSubType();
            Db::startTrans();
            switch ($notificationType) {
                    case NotificationTypeV2::CONSUMPTION_REQUEST:
                        break;
                    case NotificationTypeV2::DID_CHANGE_RENEWAL_STATUS:
                        if ($subtype !== Subtype::AUTO_RENEW_ENABLED) {
                            # code...
                            //用户开启了自动续期
                        } else if ($subtype !== Subtype::AUTO_RENEW_DISABLED) {
                            //用户结束了自动续期
                        }
                        break;
                    case NotificationTypeV2::DID_FAIL_TO_RENEW:
                        //如果不是试用期，那么结束会员资格
                        if ($subtype !== Subtype::GRACE_PERIOD) {
                            Db::name("think_users")->where("uuid", $uuid)->update([
                                "is_vip" => false
                            ]);
                        }
                        break;
                    case NotificationTypeV2::EXPIRED:
                        Db::name("think_users")->where("uuid", $uuid)->update([
                            "is_vip" => false
                        ]);
                        break;
                    case NotificationTypeV2::EXTERNAL_PURCHASE_TOKEN:
                        //外部购买，暂不实现
                        break;
                    case NotificationTypeV2::GRACE_PERIOD_EXPIRED:
                        //试用结束
                        Db::name("think_users")->where("uuid", $uuid)->update([
                            "is_vip" => false,
                            "vip_expire_date" => time(),
                        ]);
                        break;
                    case NotificationTypeV2::OFFER_REDEEMED:
                        //兑换订阅
                        $expireDate = $detail->getExpiresDate() / 1000;//milliseconds;
                        Db::name("think_users")->where("uuid", $uuid)->update([
                            "is_vip" => true,
                            "vip_expire_date" => date('Y-m-d H:i:s', $expireDate),
                        ]);
                        break;
                    case NotificationTypeV2::ONE_TIME_CHARGE:
                        //当前只在sandbox环境有，所以不处理
                        break;
                    case NotificationTypeV2::PRICE_INCREASE:
                        //不处理
                        break;
                    case NotificationTypeV2::REFUND:
                        //用户退款成功了
                        $type = $detail->getType();
                        if ($type === Type::AUTO_RENEWABLE_SUBSCRIPTION) {
                            # code...
                            $revocationDate = $detail->getRevocationDate() / 1000;//milliseconds;
                            Db::name("think_users")->where("uuid", $uuid)->update([
                                "is_vip" => false,
                                "vip_expire_date" => date('Y-m-d H:i:s', $revocationDate),
                            ]);
                        } else if ($type === Type::NON_CONSUMABLE) {
                            //非消耗品,这里需要给用户添加相应的商品
                            //比如说用户购买了一个商品,退款撤回后,需要重新给用户添加这个商品
                            //这里可以通过$detail->getProductId()获取商品ID
                        } else if ($type === Type::CONSUMABLE) {
                            //消耗品,这里需要给用户添加相应的金币或其他消耗品
                            //比如说用户购买了100金币,退款撤回后,需要重新给用户添加100金币
                            //这里可以通过$detail->getProductId()获取商品ID
                        } else if ($type === Type::NON_RENEWING_SUBSCRIPTION) {
                            $revocationDate = $detail->getRevocationDate() / 1000;//milliseconds;
                            Db::name("think_users")->where("uuid", $uuid)->update([
                                "is_vip" => false,
                                "vip_expire_date" => date('Y-m-d H:i:s', $revocationDate),
                            ]);
                            //非续订订阅,这里需要给用户添加相应的订阅
                            //比如说用户购买了一个非续订订阅,退款撤回后,需要重新给用户添加这个订阅
                            //这里可以通过$detail->getProductId()获取商品ID
                        }
                        break;
                    case NotificationTypeV2::REFUND_DECLINED:
                        //苹果拒绝退款,这里需要给用户添加相应的会员或金币
                        break;
                    case NotificationTypeV2::REFUND_REVERSED:
                        //退款撤回,这里需要重新给用户添加会员或给用户添加相应金币
                        $type = $detail->getType();
                        if ($type === Type::AUTO_RENEWABLE_SUBSCRIPTION) {
                            # code...
                            $expireDate = $detail->getExpiresDate() / 1000;//milliseconds;
                            Db::name("think_users")->where("uuid", $uuid)->update([
                                "is_vip" => true,
                                "vip_expire_date" => date('Y-m-d H:i:s', $expireDate),
                            ]);
                        } else if ($type === Type::NON_CONSUMABLE) {
                            //非消耗品,这里需要给用户添加相应的商品
                            //比如说用户购买了一个商品,退款撤回后,需要重新给用户添加这个商品
                            //这里可以通过$detail->getProductId()获取商品ID
                        } else if ($type === Type::CONSUMABLE) {
                            //消耗品,这里需要给用户添加相应的金币或其他消耗品
                            //比如说用户购买了100金币,退款撤回后,需要重新给用户添加100金币
                            //这里可以通过$detail->getProductId()获取商品ID
                        } else if ($type === Type::NON_RENEWING_SUBSCRIPTION) {
                            $expireDate = $detail->getExpiresDate() / 1000;//milliseconds;
                            Db::name("think_users")->where("uuid", $uuid)->update([
                                "is_vip" => true,
                                "vip_expire_date" => date('Y-m-d H:i:s', $expireDate),
                            ]);
                            //非续订订阅,这里需要给用户添加相应的订阅
                            //比如说用户购买了一个非续订订阅,退款撤回后,需要重新给用户添加这个订阅
                            //这里可以通过$detail->getProductId()获取商品ID
                        }
                        break;
                    case NotificationTypeV2::RENEWAL_EXTENDED:
                        //服务端请求延期的通知，不处理
                        break;
                    case NotificationTypeV2::RENEWAL_EXTENSION:
                        //用不着,这里是通过Apple接口给所有订阅用户延期的回调
                        if ($subtype === Subtype::SUMMARY) {
                            # code...
                            //给所有订阅用户延期成功
                        } else if ($subtype === Subtype::FAILURE) {
                            //给所有订阅用户延期失败
                        }
                        break;
                    case NotificationTypeV2::REVOKE:
                        // A notification type that indicates that an in-app purchase the customer was entitled to through Family Sharing is no longer available through sharing. The App Store sends this notification when a purchaser disables Family Sharing for their purchase, the purchaser (or family member) leaves the family group, or the purchaser receives a refund. Your app also receives a paymentQueue(_:didRevokeEntitlementsForProductIdentifiers:) call. Family Sharing applies to non-consumable in-app purchases and auto-renewable subscriptions. For more information about Family Sharing, see Supporting Family Sharing in your app.
                        // Family Sharing被取消，这里我们不开启Family Share，所以不处理
                        break;
                    case NotificationTypeV2::DID_CHANGE_RENEWAL_PREF:
                    case NotificationTypeV2::DID_RENEW:
                    case NotificationTypeV2::SUBSCRIBED:
                        // 处理订阅成功逻辑
                        $expireDate = $detail->getExpiresDate() / 1000;//milliseconds;
                        Db::name("think_users")->where("uuid", $uuid)->update([
                            "is_vip" => true,
                            "vip_expire_date" => date('Y-m-d H:i:s', $expireDate),
                        ]);
                        break;
                    case NotificationTypeV2::TEST:
                        break;
            }
            //保存苹果订单信息
            Db::name('think_subscription_records')->insert([
                'original_transaction_id' => $detail->getOriginalTransactionId(),
                'app_account_id' => $user['user_number'],
                'transaction_id' => $detail->getTransactionId(),
                'product_id' => $detail->getProductId(),
                'purchase_date' => $detail->getPurchaseDate() ? date('Y-m-d H:i:s', intval($detail->getPurchaseDate() / 1000)) : null,
                'expires_date' => $detail->getExpiresDate() ? date('Y-m-d H:i:s', intval($detail->getExpiresDate() / 1000)) : null,
                'environment' => $detail->getEnvironment(),
                'currency' => $detail->getCurrency(),
                'price' => $detail->getPrice(),
                'create_time' => date('Y-m-d H:i:s', time()),
                'update_time' => date('Y-m-d H:i:s', time()),
                "web_order_line_item_id"=> $detail->getWebOrderLineItemId(),
                "bundle_id" => $detail->getBundleId(),
                "subscription_group_identifier"=> $detail->getSubscriptionGroupIdentifier(),
                "original_purchase_date" => $detail->getOriginalPurchaseDate() ? date('Y-m-d H:i:s', intval($detail->getOriginalPurchaseDate() / 1000)) : null,
                "signed_date" => $detail->getSignedDate() ? date('Y-m-d H:i:s', intval($detail->getSignedDate() / 1000)) : null,
                "revocation_date" => $detail->getRevocationDate() ? date('Y-m-d H:i:s', intval($detail->getRevocationDate() / 1000)) : null,
                "quantity" => $detail->getQuantity(),
                "type" => $detail->getType(),
                "in_app_ownership_type" => $detail->getInAppOwnershipType(),
                "revocation_reason" => $detail->getRevocationReason(),
                "is_upgraded" => $detail->getIsUpgraded(),
                "offer_type" => $detail->getOfferType(),
                "offer_identifier" => $detail->getOfferIdentifier(),
                "offer_discount_type" => $detail->getOfferDiscountType(),
                "offer_period" => $detail->getOfferPeriod(),
                "storefront" => $detail->getStorefront(),
                "storefront_id" => $detail->getStorefrontId(),
                "transaction_reason" => $detail->getTransactionReason(),
                "app_transaction_id" => $detail->getAppTransactionId(),
            ]);
            Db::commit();
        } catch (APIException $e) {
            var_dump($e);
        }
    }

    
}